﻿B4J=true
Group=Default Group\数据库帮助类
ModulesStructureVersion=1
Type=Class
Version=10.3
@EndOfDesignText@
'' 全局变量
Sub Class_Globals
	Private driverClass As String = "jdbc.RedisDriver" ''驱动器
	Private host As String = "192.168.31.168" '' IP地址
	Private port As Int=26379 ''端口
	Private dataBase As Int=0 ''数据库
	Private userName As String="default" '' 7.0后默认用户名default，7.0之前为root
	Private password As String="nas!@#redis#@!" ''密码
	Private redis As SQL
End Sub

'' 初始化信息
'' 标准
''jdbc:redis://[[<user>:]<password>@][<host>[:<port>]][/<database>][?<property1>=<value>&<property2>=<value>&...]
'' 集群
''jdbc:redis:cluster://[[<user>:]<password>@][<host1>[:<port1>],<host2>[:<port2>],...][/<database>][?<property1>=<value>&<property2>=<value>&...]
Public Sub Initialize
	Dim redisUrl As String=$"jdbc:redis://${host}:${port}/${dataBase}?connectionTimeout=1000&socketTimeout=3000"$
	redis.Initialize2(driverClass,redisUrl,userName,password)
	If redis.IsInitialized Then
		LogHelper.WirteLog("Redis 初始化成功！")
		Try
			Dim rs As ResultSet
			rs = redis.ExecQuery("dbsize")
			If rs.NextRow Then
				LogHelper.WirteLog("当前redis数据库大小为：" & rs.GetInt2(0))
			End If
		Catch
			LogHelper.WirteErrorLog("Redis链接异常:" & LastException.Message)
		End Try
	End If
End Sub

'' 关闭连接
Public Sub Close
	If redis.IsInitialized Then
		redis.Close
		LogHelper.WirteLog("Redis连接已关闭")
	End If
End Sub

''============================= 键操作 =============================

'' 判断键是否存在
'' 返回值：True=存在，False=不存在
Public Sub Exists(key As String) As Boolean
	If Not(redis.IsInitialized) Then Return False
	Try
		Dim rs As ResultSet = redis.ExecQuery($"exists ${key}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0) = 1
		End If
	Catch
		LogHelper.WirteErrorLog($"判断键${key}是否存在失败: ${LastException.Message}"$)
	End Try
	Return False
End Sub

'' 删除键
'' 返回值：删除的键数量
Public Sub Del(key As String) As Int
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"del ${key}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"删除键${key}失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub

'' 设置键过期时间(秒)
'' 返回值：1=设置成功，0=设置失败
Public Sub Expire(key As String, seconds As Int) As Double
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"expire ${key} ${seconds}"$)
		If rs.NextRow Then
			'' LogHelper.WirteLog(rs.GetColumnName(0))
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"设置键${key}过期时间失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub


'' 获取键剩余过期时间(秒)
'' 返回值：剩余秒数，-1=永不过期，-2=键不存在
Public Sub Ttl(key As String) As Int
	If Not(redis.IsInitialized) Then Return -2
	Try
		Dim rs As ResultSet = redis.ExecQuery($"ttl ${key}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"获取键${key}剩余时间失败: ${LastException.Message}"$)
	End Try
	Return -2
End Sub

'' 查找匹配的键
'' pattern: 匹配模式，如"user:*"
Public Sub Keys(pattern As String) As List
	Dim result As List
	result.Initialize
	If Not(redis.IsInitialized) Then Return result
	
	Try
		Dim rs As ResultSet = redis.ExecQuery($"keys ${pattern}"$)
		Do While rs.NextRow
			result.Add(rs.GetString2(0))
		Loop
	Catch
		LogHelper.WirteErrorLog($"查找键${pattern}失败: ${LastException.Message}"$)
	End Try
	Return result
End Sub

''============================= 字符串操作 =============================

'' 设置字符串值
'' 返回值：True=成功，False=失败
Public Sub SetString(key As String, value As String) As Boolean
	If Not(redis.IsInitialized) Then Return False
	Try
		redis.ExecNonQuery($"set ${key} ${value}"$)
		Return True
	Catch
		LogHelper.WirteErrorLog($"设置字符串${key}失败: ${LastException.Message}"$)
	End Try
	Return False
End Sub

'' 设置带过期时间的字符串值(秒)
'' 返回值：True=成功，False=失败
Public Sub SetStringEx(key As String, value As String, seconds As Int) As Boolean
	If Not(redis.IsInitialized) Then Return False
	Try
		redis.ExecNonQuery($"setex ${key} ${seconds} ${value}"$)
		Return True
	Catch
		LogHelper.WirteErrorLog($"设置带过期时间的字符串${key}失败: ${LastException.Message}"$)
	End Try
	Return False
End Sub

'' 获取字符串值
'' 返回值：键对应的值，不存在则返回空字符串
Public Sub GetString(key As String) As String
	If Not(redis.IsInitialized) Then Return ""
	Try
		Dim rs As ResultSet = redis.ExecQuery($"get ${key}"$)
		If rs.NextRow Then
			Return rs.GetString2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"获取字符串${key}失败: ${LastException.Message}"$)
	End Try
	Return ""
End Sub

'' 自增1
'' 返回值：自增后的值
Public Sub Incr(key As String) As Long
	If Not(redis.IsInitialized) Then Return -1
	Try
		Dim rs As ResultSet = redis.ExecQuery($"incr ${key}"$)
		If rs.NextRow Then
			Return rs.GetLong2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"自增键${key}失败: ${LastException.Message}"$)
	End Try
	Return -1
End Sub

'' 自减1
'' 返回值：自减后的值
Public Sub Decr(key As String) As Long
	If Not(redis.IsInitialized) Then Return -1
	Try
		Dim rs As ResultSet = redis.ExecQuery($"decr ${key}"$)
		If rs.NextRow Then
			Return rs.GetLong2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"自减键${key}失败: ${LastException.Message}"$)
	End Try
	Return -1
End Sub

''============================= 哈希操作 =============================

'' 设置哈希字段值
'' 返回值：1=新字段设置成功，0=字段已存在并更新成功
Public Sub HSet(key As String, field As String, value As String) As Int
	If Not(redis.IsInitialized) Then Return -1
	Try
		Dim rs As ResultSet = redis.ExecQuery($"hset ${key} ${field} ${value}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"设置哈希${key}的字段${field}失败: ${LastException.Message}"$)
	End Try
	Return -1
End Sub

'' 获取哈希字段值
'' 返回值：字段对应的值，不存在则返回空字符串
Public Sub HGet(key As String, field As String) As String
	If Not(redis.IsInitialized) Then Return ""
	Try
		Dim rs As ResultSet = redis.ExecQuery($"hget ${key} ${field}"$)
		If rs.NextRow Then
			Return rs.GetString2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"获取哈希${key}的字段${field}失败: ${LastException.Message}"$)
	End Try
	Return ""
End Sub

'' 获取哈希所有字段和值
'' 返回值：包含字段和值的Map
Public Sub HGetAll(key As String) As Map
	Dim result As Map
	result.Initialize
	If Not(redis.IsInitialized) Then Return result
	
	Try
		Dim rs As ResultSet = redis.ExecQuery($"hgetall ${key}"$)
		Do While rs.NextRow
			Dim field As String = rs.GetString2(0)
			Dim value As String = rs.GetString2(1)
			result.Put(field, value)
		Loop
	Catch
		LogHelper.WirteErrorLog($"获取哈希${key}所有字段失败: ${LastException.Message}"$)
	End Try
	Return result
End Sub

'' 删除哈希字段
'' 返回值：删除的字段数量
Public Sub HDel(key As String, field As String) As Int
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"hdel ${key} ${field}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"删除哈希${key}的字段${field}失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub

'' 获取哈希字段数量
'' 返回值：字段数量
Public Sub HLen(key As String) As Int
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"hlen ${key}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"获取哈希${key}字段数量失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub

''============================= 列表操作 =============================

'' 从列表左侧插入元素
'' 返回值：插入后列表的长度
Public Sub LPush(key As String, value As String) As Int
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"lpush ${key} ${value}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"列表${key}左侧插入失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub

'' 从列表右侧插入元素
'' 返回值：插入后列表的长度
Public Sub RPush(key As String, value As String) As Int
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"rpush ${key} ${value}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"列表${key}右侧插入失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub

'' 获取列表指定范围的元素
'' start: 开始索引
'' end: 结束索引，-1表示最后一个元素
'' 返回值：包含元素的列表
Public Sub LRange(key As String, starts As Int, ends As Int) As List
	Dim result As List
	result.Initialize
	If Not(redis.IsInitialized) Then Return result
	
	Try
		Dim rs As ResultSet = redis.ExecQuery($"lrange ${key} ${starts} ${ends}"$)
		Do While rs.NextRow
			result.Add(rs.GetString2(0))
		Loop
	Catch
		LogHelper.WirteErrorLog($"获取列表${key}范围元素失败: ${LastException.Message}"$)
	End Try
	Return result
End Sub

'' 获取列表长度
'' 返回值：列表长度
Public Sub LLen(key As String) As Int
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"llen ${key}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"获取列表${key}长度失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub

''============================= 集合操作 =============================

'' 向集合添加元素
'' 返回值：添加的元素数量
Public Sub SAdd(key As String, value As String) As Int
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"sadd ${key} ${value}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"向集合${key}添加元素失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub

'' 获取集合所有元素
'' 返回值：包含集合元素的列表
Public Sub SMembers(key As String) As List
	Dim result As List
	result.Initialize
	If Not(redis.IsInitialized) Then Return result
	
	Try
		Dim rs As ResultSet = redis.ExecQuery($"smembers ${key}"$)
		Do While rs.NextRow
			result.Add(rs.GetString2(0))
		Loop
	Catch
		LogHelper.WirteErrorLog($"获取集合${key}所有元素失败: ${LastException.Message}"$)
	End Try
	Return result
End Sub

'' 从集合移除元素
'' 返回值：移除的元素数量
Public Sub SRem(key As String, value As String) As Int
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"srem ${key} ${value}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"从集合${key}移除元素失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub

'' 获取集合元素数量
'' 返回值：元素数量
Public Sub SCard(key As String) As Int
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"scard ${key}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"获取集合${key}元素数量失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub

'' 判断元素是否在集合中
'' 返回值：1=存在，0=不存在
Public Sub SIsMember(key As String, value As String) As Int
	If Not(redis.IsInitialized) Then Return 0
	Try
		Dim rs As ResultSet = redis.ExecQuery($"sismember ${key} ${value}"$)
		If rs.NextRow Then
			Return rs.GetInt2(0)
		End If
	Catch
		LogHelper.WirteErrorLog($"判断元素是否在集合${key}中失败: ${LastException.Message}"$)
	End Try
	Return 0
End Sub
